package com.mjh.config.filter;

import com.alibaba.fastjson2.JSONObject;
import com.mjh.constant.AuthConstants;
import com.mjh.model.CodeEnum;
import com.mjh.model.R;
import com.mjh.model.SecurityUser;
import com.mjh.utils.JWTUtil;
import com.mjh.utils.ResponseUtils;
import com.mjh.utils.TokenManager;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class TokenFilter extends OncePerRequestFilter {
    /**
     * 执行过滤逻辑
     *
     * @param request 请求对象，用于获取请求头中的认证信息
     * @param response 响应对象，用于向客户端返回错误信息
     * @param filterChain 过滤链，用于放行合法请求
     * @throws ServletException 如果发生Servlet异常
     * @throws IOException 如果发生IO异常
     */
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private TokenManager tokenManager;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 获取请求头中的authorizationValue
        String authorizationValue = request.getHeader(AuthConstants.AUTHORIZATION);
        // 判断authorizationValue是否为空
        if(!StringUtils.hasText(authorizationValue)){
            ResponseUtils.write(response, R.FAIL(CodeEnum.TOKEN_EMPTY));
        }
        // 判断authorizationValue是否以Bearer开头
        if(!authorizationValue.startsWith(AuthConstants.BEARER)){
            ResponseUtils.write(response, R.FAIL(CodeEnum.TOKEN_EMPTY));
        }
        // 获取jwt
        String jwt_token = authorizationValue.replaceFirst(AuthConstants.BEARER, "");
        // 判断jwt是否为空
        if (!StringUtils.hasText(jwt_token)) {
            ResponseUtils.write(response, R.FAIL(CodeEnum.TOKEN_EMPTY));
        }
        // 校验jwt
        if (!JWTUtil.verifyJwt(jwt_token)) {
            ResponseUtils.write(response, R.FAIL(CodeEnum.TOKEN_INVALIDATE));
        }
        // 判断redis中是否有该jwt
        if(!redisTemplate.hasKey(AuthConstants.TOKEN_REDIS_KEY_PREFIX+jwt_token)){
            ResponseUtils.write(response, R.FAIL(CodeEnum.TOKEN_INVALIDATE));
        }
        Boolean rememberMe = Boolean.valueOf(request.getParameter("sss"));
        //token续期
        tokenManager.flushTokenTime(rememberMe,jwt_token);

        //解析jwt
        String userStr = JWTUtil.parseJwt(jwt_token);
        // 获取用户信息
        SecurityUser user = JSONObject.parseObject(userStr, SecurityUser.class);
        // 获取用户权限信息集合
        Set<SimpleGrantedAuthority> collect = user.getPermissionList().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
        // 创建认证信息
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, null, collect);
        // 将认证信息存放到Security上下文中
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);



    }
}
